import {jwtDecode} from "jwt-decode";
import {cookies} from "next/headers";
import {redirect} from "next/navigation";
import {clearAuthTokens, getAuthTokens} from "@/lib/auth";

const API_REFRESH_TOKEN_URL = "http://localhost:8000/auth/refresh";

/**
 * 封装带自动 Token 管理的 fetch 请求
 * @param url 请求地址
 * @param options 请求配置（包含 method、body、headers 等）
 * @returns 响应数据
 */
export async function fetchWithAuth(
    url: string,
    options: RequestInit = {}
): Promise<Response> {
    // 1、从cookie获取token
    const {accessToken, refreshToken} = await getAuthTokens();

    // 2、检查token是否存在
    if (!accessToken || !refreshToken) {
        console.error("未找到Token，跳转登录页");
        redirect("/login");
    }

    // 3、检查access token是否过期
    let validToken = accessToken;
    try {
        const {exp} = jwtDecode(accessToken);
        if (exp * 1000 < Date.now()) {
            // Token过期 自动刷新
            console.log("Access Token 已过期，尝试自动刷新...")
            const refreshResponse = await fetch(API_REFRESH_TOKEN_URL, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `Bearer ${refreshToken}`
                },
                body: JSON.stringify({})
            });

            if (!refreshResponse.ok) {
                throw new Error("刷新Token失败");
            }

            const {access_token} = await refreshResponse.json();
            validToken = accessToken;

            // 更新cookie
            (await cookies()).set("access_token", access_token, {
                httpOnly: true,
                maxAge: 60 * 15
            });
        }
    } catch (error) {
        console.error("Token 验证/刷新失败：",error);
        await clearAuthTokens();
    }

    // 4、发起请求 鞋带有效Token
    const headers = {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${validToken}`,
        ...options.headers,
    };

    return fetch(url, {
        ...options,
        headers,
        // 如果未指定 method，默认 POST（可根据需求调整）
        method: options.method || "POST"
    })
}